//
//  EXPersistentObject.m
//  ORM
//
//  Created by PH on 21.12.09.
//  Copyright 2009-2010 Codesign. All rights reserved.
//

#import "EXPersistentObject.h"
#import "EXObjectStore.h"
#import <objc/runtime.h>
#ifdef MB_IPHONE
#import <UIKit/UIKit.h>
#else
#import <Cocoa/Cocoa.h>
#endif

static NSMutableDictionary* ORMPersistentFieldNames;

@implementation EXPersistentObject

+ (void)initialize {
	ORMPersistentFieldNames = [[NSMutableDictionary alloc] init];
}

+ (NSString*)ORMTableName {
	return NSStringFromClass(self);
}

+ (NSSet*)ORMTransientFieldNames {
	return nil;
}

+ (NSArray*)ORMPersistentFieldNames {
	NSMutableArray* fieldNames = [ORMPersistentFieldNames objectForKey: NSStringFromClass(self)];
	if (fieldNames == nil) {
		fieldNames = [[NSMutableArray alloc] init];
		Class cls = self;
		while (cls != [NSObject class]) {
			unsigned count, i;
			Ivar* firstIvar = class_copyIvarList(cls, &count);
			for (i = 0; i < count; i++) {
				Ivar* ivar = firstIvar + i;
				NSString* name = [NSString stringWithUTF8String: ivar_getName(*ivar)];
				NSString* type = [NSString stringWithUTF8String: ivar_getTypeEncoding(*ivar)];
				if ([type characterAtIndex: 0] == '@') {
					//NSLog(@"# %@ %@", name, type);
					if ([type length] > 1) {
						NSString* propertyClassName = [type substringWithRange: NSMakeRange(2, [type length] - 3)];
						NSArray* comps = [propertyClassName componentsSeparatedByString: @"<"];
						propertyClassName = [comps objectAtIndex: 0];
						NSString* protocols = [comps count] == 1 ? @"" : [comps objectAtIndex: 1];
						//NSLog(@"# '%@'", propertyClassName);
						Class propertyClass = NSClassFromString(propertyClassName);
#ifdef MB_IPHONE
						if ([propertyClass isSubclassOfClass: [UIView class]] == NO &&
							([protocols rangeOfString: @"NSCoding"].location != NSNotFound ||
							 [propertyClass conformsToProtocol: @protocol(NSCoding)] || [propertyClass conformsToProtocol: @protocol(EXMappableObject)])) {
							[fieldNames addObject: name];
						}
#else
						if ([propertyClass isSubclassOfClass: [NSView class]] == NO &&
							([protocols rangeOfString: @"NSCoding"].location != NSNotFound ||
							 [propertyClass conformsToProtocol: @protocol(NSCoding)] || [propertyClass conformsToProtocol: @protocol(EXMappableObject)])) {
							[fieldNames addObject: name];
						}
#endif
					}
				}
			}
			free(firstIvar);
			cls = [cls superclass];
		}
		[ORMPersistentFieldNames setObject: fieldNames forKey: NSStringFromClass(self)];
		[fieldNames release];
	}
	return fieldNames;
}

/*- (void)dealloc {
	[super dealloc];
}*/

@end
